package net.heavencraft.bejeweled.jewel;

import java.util.ArrayList;
import java.util.List;
import net.heavencraft.bejeweled.Drawable;
import net.heavencraft.bejeweled.GameGrid;
import net.heavencraft.bejeweled.Bejeweled;
import processing.core.PImage;

/**
 * Represents a Jewel and its core functionality
 * 
 * @author Sven
 * @author Wesley
 * 
 */
public class Jewel implements Removeable, Drawable {

	/**
	 * The color of this jewel.
	 */
	protected JewelColor color;

	/**
	 * The image that this jewel has.
	 */
	protected PImage image;

	/**
	 * Reference to the main class.
	 */
	protected final Bejeweled main;

	/**
	 * The grid that this jewel is in.
	 */
	protected final GameGrid grid;

	/**
	 * The state of this jewel
	 */
	protected boolean selected;

	/**
	 * Represents a basic jewel that can be removed and moved.
	 * 
	 * @param main
	 *            The main processing program to draw to, can not be null.
	 * @param color
	 *            The type of the jewel.
	 */
	public Jewel(Bejeweled main, JewelColor color) {
		this.main = main;
		this.setColor(color);
		grid = main.grid;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * net.heavencraft.bejeweled.jewel.Removeable#remove(net.heavencraft.bejeweled
	 * .jewel.Jewel)
	 */
	@Override
	public int remove(Jewel source) {
		int points = 0;
		grid.removeJewel(this);
		points += color.getValue();
		return points;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see net.heavencraft.bejeweled.GameObject#draw()
	 */
	@Override
	public void draw() {
		main.image(image, this.getX(), this.getY());
		if (selected)
			main.image(main.selectedCrosshair, getX(), getY());
	}

	/**
	 * Gets the type of this jewel
	 * 
	 * @return JewelType color type
	 */
	public JewelColor getColor() {
		return color;
	}

	/**
	 * Sets the type/color of this jewel.
	 * 
	 * @param color
	 *            The color that this jewel will be set to.
	 */
	public void setColor(JewelColor color) {
		this.color = color;
		this.image = main.images.getImage(this);
		System.out.println(image);
	}

	/**
	 * Toggles the selected state of this jewel
	 */
	public void toggleSelected() {
		this.selected = !this.isSelected();
	}

	/**
	 * Gets the state of this Jewel
	 * 
	 * @return The state of this jewel
	 */
	public boolean isSelected() {
		return this.selected;
	}

	/**
	 * Checks if the specified jewel is a neighbour of this jewel
	 * 
	 * @param j
	 *            The jewel to check for
	 * @return True if the jewel is a neighbour of this jewel
	 */
	public boolean isNeighbourWith(Jewel j) {
		List<Jewel> neighbours = new ArrayList<Jewel>();
		for (Jewel o : grid.getObjectsAround(this)) {
			neighbours.add(o);
		}

		if (neighbours.contains(j))
			return true;
		else
			return false;
	}

	/**
	 * Gets a list of jewels that are neighbours
	 * 
	 * @return A list of jewels around
	 */
	public Jewel[] getNeighbours() {
		return grid.getObjectsAround(this);
	}

	/**
	 * Gets the X coordinate of this jewel on the screen
	 * 
	 * @return The screen X coordinate
	 */
	private int getX() {
		return grid.getLocation(this).x * Bejeweled.jewelSize + grid.getX();
	}

	/**
	 * Gets the Y coordinate of this jewel on the screen
	 * 
	 * @return The screen Y coordinate
	 */
	private int getY() {
		return grid.getLocation(this).y * Bejeweled.jewelSize + grid.getY();
	}
}
